package com.xdqzy.baseline.common.utils;

import com.xdqzy.baseline.common.config.ServerConfigProperties;
import com.xdqzy.baseline.common.constant.CommonConstants;
import com.xdqzy.baseline.common.enums.RespCode;
import com.xdqzy.baseline.common.exception.BusinessException;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.InputStream;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
public class WebRequestUtils {

    private WebRequestUtils() {

    }

    public static Cookie[] getCookie(HttpServletRequest request) {
        return request.getCookies();
    }

    private static final String UNKNOWN = "unknown";

    /**
     * 获取ip地址
     *
     * @return
     */
    public static String getIpAddr(HttpServletRequest request) {
        String ipAddress = request.getHeader("x-forwarded-for");

        if ((ipAddress == null) || (ipAddress.length() == 0)
                || (UNKNOWN.equalsIgnoreCase(ipAddress))) {
            ipAddress = request.getHeader("Proxy-Client-IP");
        }
        if ((ipAddress == null) || (ipAddress.length() == 0)
                || (UNKNOWN.equalsIgnoreCase(ipAddress))) {
            ipAddress = request.getHeader("WL-Proxy-Client-IP");
        }
        if ((ipAddress == null) || (ipAddress.length() == 0)
                || (UNKNOWN.equalsIgnoreCase(ipAddress))) {
            ipAddress = request.getRemoteAddr();
        }

        if ((ipAddress != null) && (ipAddress.length() > 15)
                && (ipAddress.indexOf(',') >= 0)) {
            ipAddress = ipAddress.substring(0, ipAddress.indexOf(','));
        }

        return ipAddress;
    }

    /**
     * 解析文件类型
     *
     * @param file
     * @param defaultType
     * @return
     */
    public static String getUploadFileType(MultipartFile file, String defaultType) {
        String name = file.getOriginalFilename();
        if (!name.contains(CommonConstants.DOT)) {
            log.warn("can't exact file type for name :{} size :{} , fall back default type :{}", name, file.getSize(), defaultType);
            return defaultType;
        }
        return name.substring(name.lastIndexOf('.'));
    }

    public static String batchUploadImages(MultipartFile[] files, String defaultType, String uploadDir, ServerConfigProperties serverConfigProperties) {
        List<String> fileTypes = Lists.newArrayList();
        for (MultipartFile multipartFile : files) {
            String type = getUploadFileType(multipartFile, defaultType);
            if (!ArrayUtils.contains(CommonConstants.IMAGE_TYPES, type)) {
                throw new BusinessException(RespCode.IMAGE_ILLEGAL);
            }
            fileTypes.add(type);
        }
        List<String> urls = new ArrayList<>(files.length);
        for (int i = 0; i < files.length; i++) {
            MultipartFile file = files[i];
            String fileType = fileTypes.get(i);
            File dest = new File(serverConfigProperties.buildRandomFilePath(uploadDir, fileType));
            copyFile(file, dest);
            urls.add(serverConfigProperties.buildFileUrl(uploadDir, dest.getName()));
        }
        return StringUtils.join(urls, ",");
    }


    public static HttpServletRequest getRequest() {
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        return requestAttributes.getRequest();
    }

    public static void copyFile(MultipartFile file, File destFile) {
        try (InputStream stream = file.getInputStream()) {
            FileUtils.copyInputStreamToFile(stream, destFile);
        } catch (Exception e) {
            log.error("copy file error", e);
        }
    }


    public static Map<String, String> getHeaders(HttpServletRequest request) {
        Enumeration<String> headerNames = request.getHeaderNames();
        Map<String, String> headers = Maps.newHashMap();
        while (headerNames.hasMoreElements()) {
            String header = headerNames.nextElement();
            headers.put(header, request.getHeader(header));
        }
        return headers;
    }

    public static String getRequestParam(HttpServletRequest request) {
        Map<String, String[]> parameterMap = request.getParameterMap();
        return Optional.ofNullable(parameterMap).orElse(Collections.emptyMap()).entrySet().stream().map(e -> e.getKey() + ":" + StringUtils.join(e.getValue(), ",")).collect(Collectors.joining(";"));
    }
}
